﻿// Decompiled with JetBrains decompiler
// Type: DnProcessSimulateCommands.CApCableObjectAttributeObserver
// Assembly: DnProcessSimulateCommands, Version=2402.0.0.890, Culture=neutral, PublicKeyToken=null
// MVID: A885D881-AEDF-447E-852A-6F13102E089C
// Assembly location: C:\Program Files\Tecnomatix_2402\eMPower\DotNetCommands\DnProcessSimulateCommands.dll

using DnProcessSimulateCommands.Flexibles;
using EngineeringInternalExtension;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using Tecnomatix.Engineering;


namespace DnProcessSimulateCommands;

public class CApCableObjectAttributeObserver : IDisposable
{
  private readonly ICApFLEXCableAttributeViewModel m_attributeViewModel;
  private readonly ITxObjectRoot m_physicalRoot;
  private readonly CApFlexCableController m_cableController;
  private readonly CApCableAttachmentsNewUserControl m_attachmentsUserControl;

  public CApCableObjectAttributeObserver(
    ICApFLEXCableAttributeViewModel attributeViewModel,
    ITxObjectRoot physicalRoot,
    CApFlexCableController cableController,
    CApCableAttachmentsNewUserControl attachmentsUserControl)
  {
    this.m_attributeViewModel = attributeViewModel ?? throw new ArgumentNullException(nameof (attributeViewModel));
    this.m_physicalRoot = physicalRoot ?? throw new ArgumentNullException(nameof (physicalRoot));
    this.m_cableController = cableController ?? throw new ArgumentNullException(nameof (cableController));
    this.m_attachmentsUserControl = attachmentsUserControl ?? throw new ArgumentNullException(nameof (attachmentsUserControl));
    this.RegisterToEvents();
  }

  public void Dispose() => this.UnregisterFromEvents();

  private void RegisterToEvents()
  {
    this.RegisterToViewModel();
    foreach (ITxObject observedObject in this.GetObservedObjects())
      this.RegisterToObjectEvents(observedObject);
  }

  private void UnregisterFromEvents()
  {
    this.UnregisterFromViewModel();
    foreach (ITxObject observedObject in this.GetObservedObjects())
      this.UnregisterFromObjectEvents(observedObject);
  }

  private void RegisterToViewModel()
  {
    this.m_attributeViewModel.PropertyWillChange += new PropertyChangedEventHandler(this.AttributeViewModel_PropertyWillChange);
    this.m_attributeViewModel.PropertyChanged += new PropertyChangedEventHandler(this.AttributeViewModel_PropertyChanged);
  }

  private void UnregisterFromViewModel()
  {
    this.m_attributeViewModel.PropertyWillChange -= new PropertyChangedEventHandler(this.AttributeViewModel_PropertyWillChange);
    this.m_attributeViewModel.PropertyChanged -= new PropertyChangedEventHandler(this.AttributeViewModel_PropertyChanged);
  }

  private void RegisterToObjectEvents(ITxObject txObject)
  {
    switch (txObject)
    {
      case null:
        break;
      case ITxCable _:
        this.RegisterToCableEvents();
        break;
      case ITxObjectRoot itxObjectRoot:
        itxObjectRoot.ItemCreated += new TxObjectRoot_ItemCreatedEventHandler(this.PhysicalRoot_ItemCreated);
        break;
      default:
        txObject.NameChanged += new TxObject_NameChangedEventHandler(this.TxObject_NameChanged);
        if (!(txObject is ITxLocatableObject itxLocatableObject))
          break;
        itxLocatableObject.AbsoluteLocationChanged += new TxLocatableObject_AbsoluteLocationChangedEventHandler(this.TxObject_AbsoluteLocationChanged);
        itxLocatableObject.AttachmentParentChanged += new TxLocatableObject_AttachmentParentChangedEventHandler(this.TxObject_AttachmentParentChanged);
        break;
    }
  }

  private void UnregisterFromObjectEvents(ITxObject txObject)
  {
    switch (txObject)
    {
      case null:
        break;
      case ITxCable _:
        this.UnregisterFromCableEvents();
        break;
      case ITxObjectRoot itxObjectRoot:
        itxObjectRoot.ItemCreated -= new TxObjectRoot_ItemCreatedEventHandler(this.PhysicalRoot_ItemCreated);
        break;
      default:
        txObject.NameChanged -= new TxObject_NameChangedEventHandler(this.TxObject_NameChanged);
        if (!(txObject is ITxLocatableObject itxLocatableObject))
          break;
        itxLocatableObject.AbsoluteLocationChanged -= new TxLocatableObject_AbsoluteLocationChangedEventHandler(this.TxObject_AbsoluteLocationChanged);
        itxLocatableObject.AttachmentParentChanged -= new TxLocatableObject_AttachmentParentChangedEventHandler(this.TxObject_AttachmentParentChanged);
        break;
    }
  }

  private void RegisterToCableEvents()
  {
    ((ITxObject) this.Cable).NameChanged += new TxObject_NameChangedEventHandler(this.Cable_NameChanged);
    ((ITxObject) this.Cable).Deleted += new TxObject_DeletedEventHandler(this.Cable_Deleted);
    this.Cable.Modified += new TxCable_ModifiedEventHandler(this.Cable_Modified);
    if (this.Cable is ITxComponent cable)
    {
      cable.Reloaded += new TxComponent_ReloadedEventHandler(this.Cable_Reloaded);
      cable.ModelingStateChanged += new TxComponent_ModelingStateChangedEventHandler(this.Cable_ModelingStateChanged);
    }
    if (!(this.ParentEquipment is ITxComponent parentEquipment))
      return;
    parentEquipment.ModelingStateChanged += new TxComponent_ModelingStateChangedEventHandler(this.Equipment_ModelingStateChanged);
  }

  private void UnregisterFromCableEvents()
  {
    ((ITxObject) this.Cable).NameChanged -= new TxObject_NameChangedEventHandler(this.Cable_NameChanged);
    ((ITxObject) this.Cable).Deleted -= new TxObject_DeletedEventHandler(this.Cable_Deleted);
    this.Cable.Modified -= new TxCable_ModifiedEventHandler(this.Cable_Modified);
    if (this.Cable is ITxComponent cable)
    {
      cable.Reloaded -= new TxComponent_ReloadedEventHandler(this.Cable_Reloaded);
      cable.ModelingStateChanged -= new TxComponent_ModelingStateChangedEventHandler(this.Cable_ModelingStateChanged);
    }
    if (!(this.ParentEquipment is ITxComponent parentEquipment))
      return;
    parentEquipment.ModelingStateChanged -= new TxComponent_ModelingStateChangedEventHandler(this.Equipment_ModelingStateChanged);
  }

  private ITxObject GetPropertyNameObject(string propertyName)
  {
    ITxObject propertyNameObject = (ITxObject) null;
    switch (propertyName)
    {
      case "Cable":
        propertyNameObject = (ITxObject) this.Cable;
        break;
      case "StartFrame":
        propertyNameObject = (ITxObject) this.StartFrame;
        break;
      case "EndFrame":
        propertyNameObject = (ITxObject) this.EndFrame;
        break;
      case "PassNearFrame":
        propertyNameObject = (ITxObject) this.PassNearFrame;
        break;
      case "OptimizationPointCloudLayer":
        propertyNameObject = (ITxObject) this.OptimizationPointCloudLayer;
        break;
    }
    return propertyNameObject;
  }

  private string GetObjectPropertyName(object txObject)
  {
    string objectPropertyName = string.Empty;
    if (txObject == this.Cable)
      objectPropertyName = "Cable";
    else if (txObject == this.StartFrame)
      objectPropertyName = "StartFrame";
    else if (txObject == this.EndFrame)
      objectPropertyName = "EndFrame";
    else if (txObject == this.PassNearFrame)
      objectPropertyName = "PassNearFrame";
    else if (txObject == this.OptimizationPointCloudLayer)
      objectPropertyName = "OptimizationPointCloudLayer";
    return objectPropertyName;
  }

  private void UpdateUIFromCable()
  {
    this.m_cableController.UpdateViewModelWithCable(this.Cable);
    this.m_attachmentsUserControl.UpdateAttachmentDataListWithCable(this.Cable);
  }

  private IEnumerable<ITxObject> GetObservedObjects()
  {
    return (IEnumerable<ITxObject>) new List<ITxObject>(6)
    {
      (ITxObject) this.m_physicalRoot,
      (ITxObject) this.Cable,
      (ITxObject) this.StartFrame,
      (ITxObject) this.EndFrame,
      (ITxObject) this.PassNearFrame,
      (ITxObject) this.OptimizationPointCloudLayer
    };
  }

  private ITxCable Cable => this.m_attributeViewModel.Cable;

  private ITxObject ParentEquipment => this.m_attributeViewModel.CableScopeStatus.ParentEquipment;

  private ITxLocatableObject StartFrame => this.m_attributeViewModel.StartFrame;

  private ITxLocatableObject EndFrame => this.m_attributeViewModel.EndFrame;

  private ITxLocatableObject PassNearFrame => this.m_attributeViewModel.PassNearFrame;

  private ITxPointCloudLayer OptimizationPointCloudLayer
  {
    get => this.m_attributeViewModel.OptimizationPointCloudLayer;
  }

  private void AttributeViewModel_PropertyWillChange(object sender, PropertyChangedEventArgs e)
  {
    this.UnregisterFromObjectEvents(this.GetPropertyNameObject(e.PropertyName));
  }

  private void AttributeViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
  {
    this.RegisterToObjectEvents(this.GetPropertyNameObject(e.PropertyName));
  }

  private void TxObject_NameChanged(object sender, TxObject_NameChangedEventArgs args)
  {
    this.m_attributeViewModel.NotifyPropertyAttributeChanged(this.GetObjectPropertyName(sender));
  }

  private void TxObject_AbsoluteLocationChanged(
    object sender,
    TxLocatableObject_AbsoluteLocationChangedEventArgs args)
  {
    this.m_attributeViewModel.NotifyPropertyAttributeChanged(this.GetObjectPropertyName(sender));
  }

  private void TxObject_AttachmentParentChanged(
    object sender,
    TxLocatableObject_AttachmentParentChangedEventArgs args)
  {
    if (sender == this.StartFrame)
    {
      this.m_attributeViewModel.StartAttachPartTo = (ITxObject) TxEngineeringDataInternal.GetAttachmentScope(this.StartFrame);
    }
    else
    {
      if (sender != this.EndFrame)
        return;
      this.m_attributeViewModel.EndAttachPartTo = (ITxObject) TxEngineeringDataInternal.GetAttachmentScope(this.EndFrame);
    }
  }

  private void PhysicalRoot_ItemCreated(object sender, TxObjectRoot_ItemCreatedEventArgs args)
  {
    if (this.Cable == null)
      return;
    if (args.Item is ITxCable itxCable)
    {
      if (!(((ITxObject) itxCable).Id == ((ITxObject) this.Cable).Id) || this.m_attributeViewModel.IsCableBeingGenerated)
        return;
      this.UpdateUIFromCable();
    }
    else
    {
      if (!(args.Item is TxFrame txFrame))
        return;
      TxCableData cableData = this.Cable.CableData;
      if (cableData == null)
        return;
      ITxLocatableObject passNearFrame = cableData.PassNearFrame;
      if (passNearFrame != null && ((ITxObject) passNearFrame).Id == txFrame.Id)
      {
        this.UpdateUIFromCable();
      }
      else
      {
        bool flag = false;
        for (int index = 0; !flag && index < cableData.Attachments.Count; ++index)
        {
          if (((ITxObject) TxFlxCableEx.GetAttachmentFrame(this.Cable, index)).Id == txFrame.Id)
          {
            this.UpdateUIFromCable();
            flag = true;
          }
        }
      }
    }
  }

  private void Cable_NameChanged(object sender, TxObject_NameChangedEventArgs args)
  {
    this.m_attributeViewModel.CableName = ((ITxObject) this.Cable).Name;
  }

  private void Cable_Deleted(object sender, TxObject_DeletedEventArgs args)
  {
    this.m_attributeViewModel.Cable = (ITxCable) null;
  }

  private void Cable_Modified(object sender, TxCable_ModifiedEventArgs args)
  {
    if (this.m_attributeViewModel.IsCableBeingGenerated)
      return;
    this.UpdateUIFromCable();
  }

  private void Cable_Reloaded(object sender, TxComponent_ReloadedEventArgs args)
  {
    this.m_attributeViewModel.NotifyCableAttributeChanged();
    this.UpdateUIFromCable();
  }

  private void Cable_ModelingStateChanged(
    object sender,
    TxComponent_ModelingStateChangedEventArgs args)
  {
    this.m_attributeViewModel.NotifyCableAttributeChanged();
  }

  private void Equipment_ModelingStateChanged(
    object sender,
    TxComponent_ModelingStateChangedEventArgs args)
  {
    this.m_attributeViewModel.NotifyCableAttributeChanged();
  }
}
